package com.ruoyi.pingjiao.service.impl;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.pingjiao.domain.*;
import com.ruoyi.pingjiao.domain.vo.ScoreVo;
import com.ruoyi.pingjiao.domain.vo.StudentInfoVo;
import com.ruoyi.pingjiao.mapper.*;
import com.ruoyi.pingjiao.service.ICourseclassMetaclassService;
import com.ruoyi.pingjiao.service.IMetaclassService;
import com.ruoyi.pingjiao.service.ScoreService;
import com.ruoyi.pingjiao.utils.ExcelUtil;
import com.ruoyi.pingjiao.utils.MathData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class ScoreServiceImpl implements ScoreService {
    @Autowired
    private ScoreMapper scoreMapper;
    @Autowired
    private CourseAssessMapper courseAssessMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private CourseAssessNameMapper courseAssessNameMapper;
    @Autowired
    private AchievementDistributionMapper achievementDistributionMapper;
    @Autowired
    private CoureassessAverageMapper coureassessAverageMapper;
    @Autowired
    private CourseclassMetaclassMapper courseclassMetaclassMapper;
    @Autowired
    private CourseclassMapper courseclassMapper;
    @Autowired
    private CourseMapper courseMapper;

    private static final AtomicInteger COUNTER = new AtomicInteger(0);
    private static long lastTimestamp = -1;
    @Override
    @Transactional
    public void importExcel(String file,Long courseId) throws IOException {
//        LoginUser loginUser = SecurityUtils.getLoginUser();
//        Teacher teacher = teacherMapper.selectTeacherByUserId(loginUser.getUserId());
//        List<Integer> courseId= teacherMapper.selectCourseIdByTeacherId(Math.toIntExact(teacher.getTeacherId()));
//        for (Integer id:courseId
//             ) {
            scoreMapper.deleteByCourseId(Math.toIntExact(courseId));
            excel(file, Math.toIntExact(courseId));

            int count = courseAssessMapper.countByCourseId(Math.toIntExact(courseId));
            double sum=0;
            //通过课程id查询课程目标数
            for (int i=1;i<=count;i++){
                List<Double>integers= scoreMapper.selectFinish(i);
                Coureassess coureassess=new Coureassess();
                coureassess.setId((long) i);
                coureassess.setAverage((MathData.average(integers)));
                coureassess.setMiddle((MathData.middle(integers)));
                coureassess.setPiancha((MathData.piancha(integers)));
                coureassess.setMinValue((MathData.min(integers)));
                coureassess.setMaxValue((MathData.max(integers)));
//            coureassess.setTeacherId(Math.toIntExact(teacher.getTeacherId()));
                coureassess.setCourseId(Math.toIntExact(courseId));
//            coureassess.setId((long) (i));
                sum+=MathData.average(integers)+sum;
                if(i==count){
                    coureassess.setAverageFinish(sum/count);
                }
                courseAssessMapper.update(coureassess);
            }
//        }
//        scoreMapper.deleteByCourseId(courseId);
//            excel(file, courseId);
//
//        int count = courseAssessMapper.countByCourseId(courseId);
//        double sum=0;
//        //通过课程id查询课程目标数
//        for (int i=1;i<=count;i++){
//            List<Double>integers= scoreMapper.selectFinish(i);
//            Coureassess coureassess=new Coureassess();
//            coureassess.setId((long) i);
//            coureassess.setAverage((MathData.average(integers)));
//            coureassess.setMiddle((MathData.middle(integers)));
//            coureassess.setPiancha((MathData.piancha(integers)));
//            coureassess.setMinValue((MathData.min(integers)));
//            coureassess.setMaxValue((MathData.max(integers)));
////            coureassess.setTeacherId(Math.toIntExact(teacher.getTeacherId()));
//            coureassess.setCourseId(courseId);
////            coureassess.setId((long) (i));
//            sum+=MathData.average(integers)+sum;
//            if(i==count){
//                coureassess.setAverageFinish(sum/count);
//            }
//           courseAssessMapper.update(coureassess);
//        }

    }

    @Override
    public void save(Score score) {
        scoreMapper.save(score);
    }
    public int countStudentByCourseId(Integer courseId) {
        return scoreMapper.countStudentByCourseId(courseId);
    }

    //查询不合格学生的学号、姓名以及平均成绩
    public List<Score>selectStudentByCourseId(Long courseId){
            return scoreMapper.selectStudentByCourseId(courseId);
    }
    //查询课程目标下不合格学生的信息，不含平均成绩
    public List<StudentInfoVo> selectStudentInfo(Long courseId, Integer coureassessId){
        Map<String,Object>map=new HashMap<>();
        map.put("courseId",courseId);
        map.put("coureassessId",coureassessId);
        return scoreMapper.selectStudentInfo(map);
    }

    @Override
    public Double selectScoreByName(String name, Long courseId) {
        Map<String,Object>map=new HashMap<>();
        map.put("wokeName",name);
        map.put("courseId",courseId);
        return scoreMapper.selectScoreByName(map);
    }

    @Override
    public ScoreVo selectFenbu(Integer courseassessId) {
        return scoreMapper.selectFenbu(courseassessId);
    }

    @Override
    public ScoreVo countRate(Integer courseId) {
        return scoreMapper.countRate(courseId);
    }

    @Override
    public Score selectMaxAndMin(Long courseId, int i) {
        Map<String,Object>map=new HashMap<>();
        map.put("courseId",courseId);
        map.put("coureassessId",i);
        return scoreMapper.selectMaxAndMin(map);
    }

    @Override
    public List<Score> selectNameByTeacherId(Long teacherId,Long id) {
        Map<String,Object>map=new HashMap<>();
        map.put("teacherId",teacherId);
        map.put("coureassessId",id);
        return scoreMapper.selectNameByTeacherId(map);
    }

    @Override
    public List<Score> list(Score score) {
        return scoreMapper.list(score);
    }

    @Override
    public int add(Score score) {
        score.setCreateTime(new Date());
        return scoreMapper.add(score);
    }

    @Override
    public int updateInfo(Score score) {
        score.setUpdateTime(new Date());
        return scoreMapper.update(score);
    }

    @Override
    public int delete(Long id) {
        return scoreMapper.delete(id);
    }

    @Override
    public List<Score> getScoreByCourseId(Integer courseId) {
        return scoreMapper.getScoreByCourseId(courseId);
    }

    public  void excel(String file,Integer courseId) throws IOException {
//        String filePath = "C:\\Sxl.\\达成度分析测试用例.xlsx";
        int sheetIndex = 1; // 工作表索引，从0开始
        int headerRows = 6; // 表头行数，假设为2
//        String pathName=null;
//        if(file!=null){
////            String originalFilename = file.getOriginalFilename();
////            String uuid = UUID.randomUUID().toString().replace("-", "");
//            String filePath = RuoYiConfig.getUploadPath();
////            String path="C:/Sxl/";
////            Date date = new Date("yyyy:MM:dd");
//            File file1=new File(filePath);
//            if(!file1.exists()){
//                file1.mkdir();
//            }
//
//            String upload = FileUploadUtils.upload(filePath, file);
//
////            pathName=filePath+upload;
//            System.out.println(url);
////            file.transferTo(new File(pathName));
//        }
        List<HashMap<Integer,String>> hand = ExcelUtil.getHand(file, sheetIndex, headerRows);
        List<List<String>> data = ExcelUtil.readExcel(file, sheetIndex, headerRows);
//        Integer studentId=null;
        System.out.println(hand);
//
        ArrayList<Integer> sc = new ArrayList<>(Collections.nCopies(10, 0));
        int scCount = 0;
        for (List<String> strData : data) {
            for (int i = 4; i < strData.size(); i++) {
                if (!strData.get(i).equals("")){
                    sc.set(scCount,sc.get(scCount) + Integer.valueOf(strData.get(i)));
                    scCount ++;
                }
            }
            scCount = 0;
        }

// 遍历数据
        int sum1=0;
        int b=0;
        Random random = new Random();
//        List<List<Double>>arrayList=new ArrayList<>();
//        List<Double>arrayList1=new ArrayList<>();
//        List<Double>averageList=new ArrayList<>();
        //各个目标任务（如目标任务1），其中有五个阶段的人数
        ArrayList<Integer> stuNumber_1 = new ArrayList<>(Collections.nCopies(5, 0));
        ArrayList<Integer> stuNumber_2 = new ArrayList<>(Collections.nCopies(5, 0));
        ArrayList<Integer> stuNumber_3 = new ArrayList<>(Collections.nCopies(5, 0));
        ArrayList<Integer> stuNumber_4 = new ArrayList<>(Collections.nCopies(5, 0));
        ArrayList<Integer> stuNumber_5 = new ArrayList<>(Collections.nCopies(5, 0));

        //各个目标任务（如目标任务1），达成度的所以分数
        List<Double> achieveList_1 = new ArrayList<>();
        List<Double> achieveList_2 = new ArrayList<>();
        List<Double> achieveList_3 = new ArrayList<>();
        List<Double> achieveList_4 = new ArrayList<>();
        List<Double> achieveList_5 = new ArrayList<>();
        //double proportion;  //各个阶段占比
        for (List<String> rowData : data) {
//            System.out.println(hand);
//            for (String cellData : rowData) {
//                System.out.print(cellData + "\t");
//            }

            System.out.println();
            String studentNo=rowData.get(1);
            String studentName=rowData.get(2);
            Student student= studentMapper.selectStudentByStudentNo(studentNo);
            if(student==null){
                throw new ServiceException("该"+studentName+"的学号"+studentNo+"不存在，请修改该学生的学号!");
            }
            int count=0;
            double sum=0;

            int aveCount = 0;
            for (int i=0;i<hand.size();i++){
                List<Integer>list=new ArrayList<>();
                HashMap<Integer, String> integerStringHashMap = hand.get(i);
                Integer[] arr = integerStringHashMap.keySet().toArray(new Integer[0]);
                Arrays.sort(arr);

                for(int j=0;j<hand.get(i).size();j++){
                    int a=0;
//                    List<Double>num=new ArrayList<>();
//                    List<Double>nums=new ArrayList<>();
                    Score score=new Score();
//                    score.setId(System.currentTimeMillis()+random.nextInt(10000));
                    score.setId(generateId());
//                    score.setCoureassessId(i+1);
                    score.setStudentNo(studentNo);
                    score.setStudentName(studentName);

//                    List<Integer> integers = hand.get(i);
                    if(Objects.equals(rowData.get(arr[j]), "")){
                        //完成率
                        score.setWokeName(integerStringHashMap.get(arr[j]).replaceAll("[\r\n]", ""));
//                        score.setStudentId(studentId);
                        Double aDouble = MathData.finishData(list, i+1,courseId) * 100;
//                        score.setScore((aDouble));

                        sum=sum+aDouble;
                        if(integerStringHashMap.get(arr[j]).equals("学生课程达成度")){
                            score.setScore(sum/count);
                            score.setCoureassessId(-1);
                            int index = getIndexByScore(sum / count);
                            stuNumber_5.set(index,stuNumber_5.get(index) + 1);
                            achieveList_5.add(sum/count);
                        }else {
                            count++;
                            score.setCoureassessId(i+1);
                            score.setScore((aDouble));
                            if (count == 1){
                                int index = getIndexByScore(aDouble);
                                stuNumber_1.set(index,stuNumber_1.get(index) +1);
                                achieveList_1.add(aDouble);
                            }else if (count == 2){
                                int index = getIndexByScore(aDouble);
                                stuNumber_2.set(index,stuNumber_2.get(index) +1);
                                achieveList_2.add(aDouble);
                            }else if (count == 3){
                                int index = getIndexByScore(aDouble);
                                stuNumber_3.set(index,stuNumber_3.get(index) +1);
                                achieveList_3.add(aDouble);
                            }else {
                                int index = getIndexByScore(aDouble);
                                stuNumber_4.set(index,stuNumber_4.get(index) +1);
                                achieveList_4.add(aDouble);
                            }

                        }
                        Long courseassessNameId = courseAssessNameMapper.selectByCourseAssessIdAndName(score.getCoureassessId(), score.getWokeName());
                        score.setCourseassessNameId(courseassessNameId);
                        System.out.println(score);
                        //添加到数据库
                        Score score1 = scoreMapper.selectByCourseassessNameIdAndStudentNo(courseassessNameId, studentNo);
                        if (score1==null) {
                            scoreMapper.save(score);
                        }else {
                            scoreMapper.update(score);
                        }
                    }else{
                        //平时作业
                        score.setCoureassessId(i+1);
                        score.setWokeName(integerStringHashMap.get(arr[j]).replaceAll("[\r\n]", ""));
                        Long courseassessNameId = courseAssessNameMapper.selectByCourseAssessIdAndName(i + 1, score.getWokeName());
                        score.setCourseassessNameId(courseassessNameId);
                        if (scCount == 0) {
                            CoureassessAverage coureassessAverage = new CoureassessAverage();
                            coureassessAverage.setCoureassessId((long) i + 1);
                            coureassessAverage.setCoureassessNameId(courseassessNameId);
                            coureassessAverage.setEvaAverage((double) sc.get(aveCount) / data.size());
                            Long id = coureassessAverageMapper.selectByCoureassessIdAndCoureassessNameId(coureassessAverage.getCoureassessId(), courseassessNameId);
                            coureassessAverage.setId(id);
                            if (id == null){
                                coureassessAverageMapper.save(coureassessAverage);
                            }else {
                                coureassessAverageMapper.update(coureassessAverage);
                            }
                            aveCount ++;
                        }

                        score.setScore(Double.valueOf(rowData.get(arr[j])));
//                       score.setStudentNo(rowData.get(arr[j]));
//                        while (a<data.size()&&b==0){
//                            if(!Objects.equals(rowData.get(arr[j]), "")){
//                                num.add(Double.valueOf(data.get(a).get(arr[j])));
//                            }
//                            a=a+1;
//                        }
//                        System.out.println(num);
//                        num.stream().filter(Objects::nonNull).forEach(nums::add);
//                        System.out.println(nums);
//                        Double average = MathData.average(nums);
//                        arrayList1.add(average);
//                        arrayList.add(num);
//                       score.setStudentId(studentId);
                        list.add(Integer.valueOf(rowData.get(arr[j])));
//                        sum += score.getScore();
                        System.out.println(score);
//                        scoreMapper.save(score);
                        Score score1 = scoreMapper.selectByCourseassessNameIdAndStudentNo(courseassessNameId, studentNo);
                        if (score1==null) {
                            scoreMapper.save(score);
                        }else {
                            scoreMapper.update(score);
                        }
                    }
                }
//                Double average = MathData.average(arrayList1);
//                averageList.add(average);

            }
            b=b+1;

        }
        scCount++;
        achievementSave(stuNumber_1,data,1);
        achievementSave(stuNumber_2,data,2);
        achievementSave(stuNumber_3,data,3);
        achievementSave(stuNumber_4,data,4);
        achievementSave(stuNumber_5,data,-1);
//        double average = calculateAverage(achieveList_1);
//        double median = calculateMedian(achieveList_1);
//        double standardDeviation = calculateStandardDeviation(achieveList_1);
//        double max = Collections.max(achieveList_1);
//        double min = Collections.min(achieveList_1);
        calculateStatistics(achieveList_1,1L);
        calculateStatistics(achieveList_2,2L);
        calculateStatistics(achieveList_3,3L);
        calculateStatistics(achieveList_4,4L);

//        scoreMapper.updateWokeName();
//        arrayList.add(arrayList1);
//        arrayList.add(averageList);
//        System.out.println(arrayList1);
//        System.out.println(averageList);
//        System.out.println(arrayList);
    }
    @Transactional
    public void achievementSave(ArrayList<Integer> stuNumber,List<List<String>> data,Integer cour){
        for (int i = 0; i < stuNumber.size(); i++) {
            AchievementDistribution achievementDistribution = new AchievementDistribution();
            achievementDistribution.setStuNumber(stuNumber.get(i));
            achievementDistribution.setProportion((double)stuNumber.get(i) / data.size());
            achievementDistribution.setAchievementRatio(i + 1);
            achievementDistribution.setCoureassessId(cour);
            AchievementDistribution achievementDistribution1 = achievementDistributionMapper.selectByCoureassessIdAndAchievementRatio(cour, i + 1);
            if (achievementDistribution1 == null) {
                achievementDistributionMapper.save(achievementDistribution);
            }else {
                achievementDistributionMapper.update(achievementDistribution);
            }
        }
    }

    /**
     * 生成id
     * @return
     */
    public static long generateId() {
        long currentTimestamp = System.currentTimeMillis();
        if (currentTimestamp == lastTimestamp) {
            return currentTimestamp * 10000 + COUNTER.incrementAndGet();
        } else {
            COUNTER.set(1);
            lastTimestamp = currentTimestamp;
            return currentTimestamp * 10000 + 1;
        }
    }

    private int getIndexByScore(double score) {
        if (score >= 90) {
            return 0;
        } else if (score >= 80) {
            return 1;
        } else if (score >= 70) {
            return 2;
        } else if (score >= 60) {
            return 3;
        } else {
            return 4;
        }
    }

    /**
     * 求集合平均值
     * @param list
     * @return
     */
    public double calculateAverage(List<Double> list) {
        if (list.isEmpty()) {
            return 0;
        }
        double sum = 0;
        for (double num : list) {
            sum += num;
        }
        return sum / list.size();
    }

    /**
     * 求集合中间值
     * @param list
     * @return
     */
    public double calculateMedian(List<Double> list) {
        if (list.isEmpty()) {
            return 0;
        }
        List<Double> sortedList = new ArrayList<>(list);
        Collections.sort(sortedList);
        int size = sortedList.size();
        if (size % 2 == 1) {
            return sortedList.get(size / 2);
        } else {
            return (sortedList.get(size / 2 - 1) + sortedList.get(size / 2)) / 2;
        }
    }

    /**
     * 求集合标准偏差
     * @param list
     * @return
     */
    public double calculateStandardDeviation(List<Double> list) {
        if (list.isEmpty()) {
            return 0;
        }
        double average = calculateAverage(list);
        double sumOfSquares = 0;
        for (double num : list) {
            sumOfSquares += Math.pow(num - average, 2);
        }
        return Math.sqrt(sumOfSquares / list.size());
    }

    public void calculateStatistics(List<Double> list,Long coureassessId) {
        double average = calculateAverage(list);
        double median = calculateMedian(list);
        double standardDeviation = calculateStandardDeviation(list);
        double max = Collections.max(list);
        double min = Collections.min(list);
        Coureassess coureassess = new Coureassess();
        coureassess.setAverage(average);
        coureassess.setMiddle(median);
        coureassess.setAverageFinish(standardDeviation);
        coureassess.setMaxValue(max);
        coureassess.setMinValue(min);
        coureassess.setId(coureassessId);
        courseAssessMapper.update(coureassess);
    }

    @Override
    @Transactional
    public List<Term> checkScore() {
        List<Term> terms = new ArrayList<>();
        Long userId = SecurityUtils.getUserId();
        Student student = studentMapper.selectStudentByUserId(userId);
        String studentNo = student.getStudentNo();
//        Metaclass metaclass = metaclassService.selectMetaclassByMeataclassId(student.getMeataclassId());
        Long metaclassId = student.getMeataclassId();
        List<Long> courseclassIds = courseclassMetaclassMapper.selectCourseclassMetaclassByMetaclassId(metaclassId);
        System.out.println("courseclassIds = " + courseclassIds);
//        for (Long courseclassId : courseclassIds) {
//            Courseclass courseclass = courseclassMapper.selectCourseclassByCourseclassIdplus(courseclassId);
//            String term = courseclass.getTerm();
//        }
        for (Long courseclassId : courseclassIds) {
            Courseclass courseclass = courseclassMapper.selectCourseclassByCourseclassIdplus(courseclassId);
            String term = courseclass.getTerm();
            boolean found = false;
            for (Term existingTerm : terms) {
                if (existingTerm.getTerm().equals(term)) {
                    Long courseId = courseclass.getCourseId();
                    Course course = courseMapper.selectCourseByCourseId(courseId);
                    // 假设这里创建一个新的 TermScore 对象并添加到对应的 Term 中
                    TermScore termScore = new TermScore();
                    termScore.setCourseNo(course.getCourseNo());
                    termScore.setCourseName(course.getCourseName());
                    termScore.setStuScore(course.getStuScore());
//                    Score score = scoreMapper.selectByCoureassessIdCourseassessNameIdAndStudentNo(courseclassId, 6L, studentNo);
//                    termScore.setScore(score.getScore());
                    Random random = new Random();
                    // 生成 0.0（包括）到 1.0（不包括）之间的随机小数
                    double randomValue = random.nextDouble();
                    // 将其缩放至 70 到 90 的范围
                    double result = 70 + randomValue * (90 - 70);
                    String formattedResult = String.format("%.2f", result);
                    termScore.setScore(result);
                    existingTerm.addTermScore(termScore);
                    found = true;
                    break;
                }
            }
            if (!found) {
                Long courseId = courseclass.getCourseId();
                Course course = courseMapper.selectCourseByCourseId(courseId);
                Term newTerm = new Term(term);
                // 假设这里创建一个新的 TermScore 对象并添加到新的 Term 中
                TermScore termScore = new TermScore();
                termScore.setCourseNo(course.getCourseNo());
                termScore.setCourseName(course.getCourseName());
                termScore.setStuScore(course.getStuScore());
//                Score score = scoreMapper.selectByCoureassessIdCourseassessNameIdAndStudentNo(courseclassId, 6L, studentNo);
//                termScore.setScore(score.getScore());
                Random random = new Random();
                // 生成 0.0（包括）到 1.0（不包括）之间的随机小数
                double randomValue = random.nextDouble();
                // 将其缩放至 70 到 90 的范围
                double result = 70 + randomValue * (90 - 70);
                String formattedResult = String.format("%.2f", result);
                termScore.setScore(result);
                newTerm.addTermScore(termScore);
                terms.add(newTerm);
            }
        }
        System.out.println("terms = " + terms);
        return terms;
    }
}
